home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-server / xlisp / xlfio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  12.0 KB  |  526 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         xlfio.c
  5. * RCS:          $Header: xlfio.c,v 1.6 91/03/24 22:24:39 mayer Exp $
  6. * Description:  xlisp file i/o
  7. * Author:       David Michael Betz
  8. * Created:      
  9. * Modified:     Fri Oct  4 03:52:37 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. *
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: xlfio.c,v 1.6 91/03/24 22:24:39 mayer Exp $";
  42.  
  43. #include "xlisp.h"
  44.  
  45. /* external variables */
  46. extern LVAL k_direction,k_input,k_output;
  47. extern LVAL s_stdin,s_stdout,true;
  48. extern unsigned char buf[];
  49. extern int xlfsize;
  50.  
  51. /* external routines */
  52. extern FILE *osaopen();
  53.  
  54. /* forward declarations */
  55. LOCAL FORWARD LVAL getstroutput(); /* NPM: changed this to LOCAL */
  56. LOCAL FORWARD LVAL printit();    /* NPM: changed this to LOCAL */
  57. LOCAL FORWARD LVAL flatsize();    /* NPM: changed this to LOCAL */
  58. /* FORWARD LVAL openit(); */    /* NPM: commented this out since it is not defined anywhere */
  59.  
  60. /* xread - read an expression */
  61. LVAL xread()
  62. {
  63.     LVAL fptr,eof,rflag,val;
  64.  
  65.     /* get file pointer and eof value */
  66.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdin));
  67.     eof = (moreargs() ? xlgetarg() : NIL);
  68.     rflag = (moreargs() ? xlgetarg() : NIL);
  69.     xllastarg();
  70.  
  71.     /* read an expression */
  72.     if (!xlread(fptr,&val,rflag != NIL))
  73.     val = eof;
  74.  
  75.     /* return the expression */
  76.     return (val);
  77. }
  78.  
  79. /* xprint - built-in function 'print' */
  80. LVAL xprint()
  81. {
  82.     return (printit(TRUE,TRUE));
  83. }
  84.  
  85. /* xprin1 - built-in function 'prin1' */
  86. LVAL xprin1()
  87. {
  88.     return (printit(TRUE,FALSE));
  89. }
  90.  
  91. /* xprinc - built-in function princ */
  92. LVAL xprinc()
  93. {
  94.     return (printit(FALSE,FALSE));
  95. }
  96.  
  97. /* xterpri - terminate the current print line */
  98. LVAL xterpri()
  99. {
  100.     LVAL fptr;
  101.  
  102.     /* get file pointer */
  103.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdout));
  104.     xllastarg();
  105.  
  106.     /* terminate the print line and return nil */
  107.     xlterpri(fptr);
  108.     return (NIL);
  109. }
  110.  
  111. /* printit - common print function */
  112. LOCAL LVAL printit(pflag,tflag)
  113.   int pflag,tflag;
  114. {
  115.     LVAL fptr,val;
  116.  
  117.     /* get expression to print and file pointer */
  118.     val = xlgetarg();
  119.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdout));
  120.     xllastarg();
  121.  
  122.     /* print the value */
  123.     xlprint(fptr,val,pflag);
  124.  
  125.     /* terminate the print line if necessary */
  126.     if (tflag)
  127.     xlterpri(fptr);
  128.  
  129.     /* return the result */
  130.     return (val);
  131. }
  132.  
  133. /* xflatsize - compute the size of a printed representation using prin1 */
  134. LVAL xflatsize()
  135. {
  136.     return (flatsize(TRUE));
  137. }
  138.  
  139. /* xflatc - compute the size of a printed representation using princ */
  140. LVAL xflatc()
  141. {
  142.     return (flatsize(FALSE));
  143. }
  144.  
  145. /* flatsize - compute the size of a printed expression */
  146. LOCAL LVAL flatsize(pflag)
  147.   int pflag;
  148. {
  149.     LVAL val;
  150.  
  151.     /* get the expression */
  152.     val = xlgetarg();
  153.     xllastarg();
  154.  
  155.     /* print the value to compute its size */
  156.     xlfsize = 0;
  157.     xlprint(NIL,val,pflag);
  158.  
  159.     /* return the length of the expression */
  160.     return (cvfixnum((FIXTYPE)xlfsize));
  161. }
  162.  
  163. /* xopen - open a file */
  164. LVAL xopen()
  165. {
  166.     char *name,*mode;
  167.     FILE *fp;
  168.     LVAL dir;
  169.  
  170.     /* get the file name and direction */
  171.     name = (char *)getstring(xlgetfname());
  172.     if (!xlgetkeyarg(k_direction,&dir))
  173.     dir = k_input;
  174.  
  175.     /* get the mode */
  176.     if (dir == k_input)
  177.     mode = "r";
  178.     else if (dir == k_output)
  179.     mode = "w";
  180.     else
  181.     xlerror("bad direction",dir);
  182.  
  183.     /* try to open the file */
  184.     return ((fp = osaopen(name,mode)) ? cvfile(fp) : NIL);
  185. }
  186.  
  187. /* xclose - close a file */
  188. LVAL xclose()
  189. {
  190.     LVAL fptr;
  191.  
  192.     /* get file pointer */
  193.     fptr = xlgastream();
  194. #if (defined(UNIX) || defined(WINTERP))
  195.     if (ntype(fptr) == XLTYPE_PIPE)
  196.       xlfail("Pipes must be closed with PCLOSE, not CLOSE.");
  197. #endif /* (defined(UNIX) || defined(WINTERP)) */
  198.     xllastarg();
  199.  
  200.     /* make sure the file exists */
  201.     if (getfile(fptr) == NULL)
  202.     xlfail("file not open");
  203.  
  204.     /* close the file */
  205.     osclose(getfile(fptr));
  206.     setfile(fptr,NULL);
  207.  
  208.     /* return nil */
  209.     return (NIL);
  210. }
  211.  
  212. /* xrdchar - read a character from a file */
  213. LVAL xrdchar()
  214. {
  215.     LVAL fptr;
  216.     int ch;
  217.  
  218.     /* get file pointer */
  219.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdin));
  220.     xllastarg();
  221.  
  222.     /* get character and check for eof */
  223.     return ((ch = xlgetc(fptr)) == EOF ? NIL : cvchar(ch));
  224. }
  225.  
  226. /* xrdbyte - read a byte from a file */
  227. LVAL xrdbyte()
  228. {
  229.     LVAL fptr;
  230.     int ch;
  231.  
  232.     /* get file pointer */
  233.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdin));
  234.     xllastarg();
  235.  
  236.     /* get character and check for eof */
  237.     return ((ch = xlgetc(fptr)) == EOF ? NIL : cvfixnum((FIXTYPE)ch));
  238. }
  239.  
  240. /* xpkchar - peek at a character from a file */
  241. LVAL xpkchar()
  242. {
  243.     LVAL flag,fptr;
  244.     int ch;
  245.  
  246.     /* peek flag and get file pointer */
  247.     flag = (moreargs() ? xlgetarg() : NIL);
  248.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdin));
  249.     xllastarg();
  250.  
  251.     /* skip leading white space and get a character */
  252.     if (flag)
  253.     while ((ch = xlpeek(fptr)) != EOF && isspace(ch))
  254.         xlgetc(fptr);
  255.     else
  256.     ch = xlpeek(fptr);
  257.  
  258.     /* return the character */
  259.     return (ch == EOF ? NIL : cvchar(ch));
  260. }
  261.  
  262. /* xwrchar - write a character to a file */
  263. LVAL xwrchar()
  264. {
  265.     LVAL fptr,chr;
  266.  
  267.     /* get the character and file pointer */
  268.     chr = xlgachar();
  269.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdout));
  270.     xllastarg();
  271.  
  272.     /* put character to the file */
  273.     xlputc(fptr,getchcode(chr));
  274.  
  275.     /* return the character */
  276.     return (chr);
  277. }
  278.  
  279. /* xwrbyte - write a byte to a file */
  280. LVAL xwrbyte()
  281. {
  282.     LVAL fptr,chr;
  283.  
  284.     /* get the byte and file pointer */
  285.     chr = xlgafixnum();
  286.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdout));
  287.     xllastarg();
  288.  
  289.     /* put byte to the file */
  290.     xlputc(fptr,(int)getfixnum(chr));
  291.  
  292.     /* return the character */
  293.     return (chr);
  294. }
  295.  
  296. /* xreadline - read a line from a file */
  297. LVAL xreadline()
  298. {
  299.     unsigned char buf[STRMAX+1],*p,*sptr;
  300.     LVAL fptr,str,newstr;
  301.     int len,blen,ch;
  302.  
  303.     /* protect some pointers */
  304.     xlsave1(str);
  305.  
  306.     /* get file pointer */
  307.     fptr = (moreargs() ? xlgetfile() : getvalue(s_stdin));
  308.     xllastarg();
  309.  
  310.     /* get character and check for eof */
  311.     len = blen = 0; p = buf;
  312.     while ((ch = xlgetc(fptr)) != EOF && ch != '\n') {
  313.  
  314.     /* check for buffer overflow */
  315.     if (blen >= STRMAX) {
  316.          newstr = newstring(len + STRMAX + 1);
  317.         sptr = getstring(newstr); *sptr = '\0';
  318.         if (str) strcat(sptr,getstring(str));
  319.         *p = '\0'; strcat(sptr,buf);
  320.         p = buf; blen = 0;
  321.         len += STRMAX;
  322.         str = newstr;
  323.     }
  324.  
  325.     /* store the character */
  326.     *p++ = ch; ++blen;
  327.     }
  328.  
  329.     /* check for end of file */
  330.     if (len == 0 && p == buf && ch == EOF) {
  331.     xlpop();
  332.     return (NIL);
  333.     }
  334.  
  335.     /* append the last substring */
  336.     if (str == NIL || blen) {
  337.     newstr = newstring(len + blen + 1);
  338.     sptr = getstring(newstr); *sptr = '\0';
  339.     if (str) strcat(sptr,getstring(str));
  340.     *p = '\0'; strcat(sptr,buf);
  341.     str = newstr;
  342.     }
  343.  
  344.     /* restore the stack */
  345.     xlpop();
  346.  
  347.     /* return the string */
  348.     return (str);
  349. }
  350.  
  351.  
  352. /* xmkstrinput - make a string input stream */
  353. LVAL xmkstrinput()
  354. {
  355.     int start,end,len,i;
  356.     unsigned char *str;
  357.     LVAL string,val;
  358.  
  359.     /* protect the return value */
  360.     xlsave1(val);
  361.     
  362.     /* get the string and length */
  363.     string = xlgastring();
  364.     str = getstring(string);
  365.     len = getslength(string) - 1;
  366.  
  367.     /* get the starting offset */
  368.     if (moreargs()) {
  369.     val = xlgafixnum();
  370.     start = (int)getfixnum(val);
  371.     }
  372.     else start = 0;
  373.  
  374.     /* get the ending offset */
  375.     if (moreargs()) {
  376.     val = xlgafixnum();
  377.     end = (int)getfixnum(val);
  378.     }
  379.     else end = len;
  380.     xllastarg();
  381.  
  382.     /* check the bounds */
  383.     if (start < 0 || start > len)
  384.     xlerror("string index out of bounds",cvfixnum((FIXTYPE)start));
  385.     if (end < 0 || end > len)
  386.     xlerror("string index out of bounds",cvfixnum((FIXTYPE)end));
  387.  
  388.     /* make the stream */
  389.     val = newustream();
  390.  
  391.     /* copy the substring into the stream */
  392.     for (i = start; i < end; ++i)
  393.     xlputc(val,str[i]);
  394.  
  395.     /* restore the stack */
  396.     xlpop();
  397.  
  398.     /* return the new stream */
  399.     return (val);
  400. }
  401.  
  402. /* xmkstroutput - make a string output stream */
  403. LVAL xmkstroutput()
  404. {
  405.     return (newustream());
  406. }
  407.  
  408. /* xgetstroutput - get output stream string */
  409. LVAL xgetstroutput()
  410. {
  411.     LVAL stream;
  412.     stream = xlgaustream();
  413.     xllastarg();
  414.     return (getstroutput(stream));
  415. }
  416.  
  417. /* xgetlstoutput - get output stream list */
  418. LVAL xgetlstoutput()
  419. {
  420.     LVAL stream,val;
  421.  
  422.     /* get the stream */
  423.     stream = xlgaustream();
  424.     xllastarg();
  425.  
  426.     /* get the output character list */
  427.     val = gethead(stream);
  428.  
  429.     /* empty the character list */
  430.     sethead(stream,NIL);
  431.     settail(stream,NIL);
  432.  
  433.     /* return the list */
  434.     return (val);
  435. }
  436.  
  437. /* xformat - formatted output function */
  438. LVAL xformat()
  439. {
  440.     LVAL fmtstring,stream,val;
  441.     unsigned char *fmt;
  442.     int ch;
  443.  
  444.     /* protect some pointers */
  445.     xlstkcheck(2);
  446.     xlsave(fmtstring);
  447.     xlsave(stream);
  448.  
  449.     /* get the stream and format string */
  450.     stream = xlgetarg();
  451.     if (stream == NIL)
  452.     val = stream = newustream();
  453.     else {
  454.     if (stream == true)
  455.         stream = getvalue(s_stdout);
  456.     else if (!streamp(stream) && !ustreamp(stream))
  457.         xlbadtype(stream);
  458.     val = NIL;
  459.     }
  460.     fmtstring = xlgastring();
  461.     fmt = getstring(fmtstring);
  462.  
  463.     /* process the format string */
  464.     while (ch = *fmt++)
  465.     if (ch == '~') {
  466.         switch (*fmt++) {
  467.         case '\0':
  468.         xlerror("expecting a format directive",cvstring(fmt-1));
  469.         case 'a': case 'A':
  470.         xlprint(stream,xlgetarg(),FALSE);
  471.         break;
  472.         case 's': case 'S':
  473.         xlprint(stream,xlgetarg(),TRUE);
  474.         break;
  475.         case '%':
  476.         xlterpri(stream);
  477.         break;
  478.         case '~':
  479.         xlputc(stream,'~');
  480.         break;
  481.         case '\n':
  482.         while (*fmt && *fmt != '\n' && isspace(*fmt))
  483.             ++fmt;
  484.         break;
  485.         default:
  486.         xlerror("unknown format directive",cvstring(fmt-1));
  487.         }
  488.     }
  489.     else
  490.         xlputc(stream,ch);
  491.     
  492.     /* get the output string for a stream argument of NIL */
  493.     if (val) val = getstroutput(val);
  494.     xlpopn(2);
  495.         
  496.     /* return the value */
  497.     return (val);
  498. }
  499.  
  500. /* getstroutput - get the output stream string (internal) */
  501. LOCAL LVAL getstroutput(stream)
  502.   LVAL stream;
  503. {
  504.     unsigned char *str;
  505.     LVAL next,val;
  506.     int len,ch;
  507.  
  508.     /* compute the length of the stream */
  509.     for (len = 0, next = gethead(stream); next != NIL; next = cdr(next))
  510.     ++len;
  511.  
  512.     /* create a new string */
  513.     val = newstring(len + 1);
  514.     
  515.     /* copy the characters into the new string */
  516.     str = getstring(val);
  517.     while ((ch = xlgetc(stream)) != EOF)
  518.     *str++ = ch;
  519.     *str = '\0';
  520.  
  521.     /* return the string */
  522.     return (val);
  523. }
  524.  
  525.